#include "easy_sock.h"

#define BACKLOG 10

int open_listen(const short port)
{
    int sockfd;
    struct sockaddr_in my_addr;
    PCHECK(sockfd=socket( AF_INET,SOCK_STREAM, 0 ), "socket" );
    my_addr.sin_family=AF_INET;
    my_addr.sin_port=htons(port);
    my_addr.sin_addr.s_addr = INADDR_ANY;
    memset( &(my_addr.sin_zero),0x00,8 );
    PCHECK(bind(sockfd,(struct sockaddr *)&my_addr, sizeof(struct sockaddr)) ,"bind" );
    PCHECK(listen(sockfd,BACKLOG), "listen" );
    return sockfd;
}

void makesockaddr(struct sockaddr_in *addr,const char *ip,const short port)
{
    addr->sin_family=AF_INET;
    addr->sin_port = htons(port);
    addr->sin_addr.s_addr = inet_addr(ip);
    bzero(&(addr->sin_zero),8);
}

int connect_to(const char *ip, const short port)
{
    int sfd;
    struct sockaddr_in s_addr;

    memset( &s_addr, 0x00, sizeof(struct sockaddr_in) );
    makesockaddr( &s_addr, ip, port );
    PCHECK(sfd=socket( AF_INET,SOCK_STREAM, 0 ), "socket" );
    PCHECK(connect( sfd, (struct sockaddr *)&s_addr, sizeof(struct sockaddr)), "connect" );
    
    return sfd;
}

int close_sock(MSOCK *msock)
{
    while(1)
    {
        if( (msock->sflag==0) && (msock->rflag==0) )
        {
            close(msock->sock_fd);
            free(msock);
            mlog("demo.log", _FL_, "socket close");
            return 0;
        }
    }
    
    /*never get here*/
    return 0;
}

/*init a msock struct*/
/*
input:
cfd    an opened handle of a connection
output:
msock  a msock struct
*/
int init_msock( int cfd, MSOCK** tmsock)
{
        MSOCK *msock;
        msock = (MSOCK *)malloc(sizeof(MSOCK));
        msock->sock_fd = cfd;
        msock->rflag = 0;
        msock->sflag = 0;
        msock->length = 0;
        memset( msock->sbuf, 0x00, sizeof(msock->sbuf) );
        pthread_mutex_init( &(msock->buf_lock), NULL );
        *tmsock=msock;
        return 0;
}